#include "BondDetailAllMarket.h"

#include <core/StyleMgr.h>
#include <qbtools/tools.h>
#include <uam/UserAccountManager.h>
#include <widgets/table/STable.h>
#include <widgets/table/STableColumnSet.h>

#include <QHeaderView>
#include <QStylePainter>
#include <QTableView>
#include <QVector>

#include "../BondColDelegate.h"
#include "../BondUtility.h"
#include "BondDetailData.h"
#include "DetailQuoteTable.h"
#include "ui_BondDetailAllMarket.h"

const char kAll[] = "不限";
const char kT0[] = "T+0";
const char kT1[] = "T+1";
const char kFWD[] = "远期";
const char kSpot[] = "非远期";

namespace BestTableColumnID {
const int Type = 0;
const int Buyer = 1;
const int VolBid = 2;
const int Bid = 3;
const int Ofr = 4;
const int VolOfr = 5;
const int Seller = 6;
const int UpdateTime = 7;
const int MAX_COL_COUNT = 8;
};  // namespace BestTableColumnID

const int MARKET_SHFI = 110;      //上证固收
const int MARKET_EXCHANGE = 111;  //交易所
const int MARKET_CFETS = 112;     // CFETS

const char MARKET_NAME_BROKER[] = "经纪商";
const char MARKET_NAME_EXCHANGE[] = "交易所";
const char MARKET_NAME_SHFI[] = "上证固收";
const char MARKET_NAME_CFETS[] = "CFETS";
const QStringList kMarkNameList = {"", MARKET_NAME_BROKER, MARKET_NAME_CFETS,
                                   MARKET_NAME_EXCHANGE, MARKET_NAME_SHFI};

const int kRowHeight = 24;

BondDetailAllMarket::BondDetailAllMarket(QWidget* parent)
    : QWidget(parent), ui(new Ui::BondDetailAllMarket) {
  ui->setupUi(this);

  m_bestTable = ui->QuoteTable;
  m_bestBidOfr = ui->BestBOBroker;

  const QColor& normal = StyleMgr::instance().color("ButtonDisable");
  const QColor& hover = StyleMgr::instance().color("Hover");
  const QColor& checked_bkg = StyleMgr::instance().color("BackNormal");
  const QColor& checked = StyleMgr::instance().color("TabSelBorder");
  // const QColor& text = StyleMgr::instance().color("ChartH8");
  const auto& buttons = ui->buttonGroup->buttons();
  for (auto button : buttons) {
    button->setStyleSheet(QString("QPushButton {"
                                  "  background-color: #%1;"
                                  "}"
                                  "QPushButton:hover {"
                                  "  background-color: #%2;"
                                  "}"
                                  "QPushButton:checked {"
                                  "  border: 1px solid #%3;"
                                  "  color: #%3;"
                                  "  background-color: #%4;"
                                  "}")
                              .arg(normal.rgb(), 0, 16)
                              .arg(hover.rgb(), 0, 16)
                              .arg(checked.rgb(), 0, 16)
                              .arg(checked_bkg.rgb(), 0, 16));
  }

  ui->buttonGroup->setId(ui->btnTickByTick, TickByTick);
  ui->buttonGroup->setId(ui->btnTodaysDeals, TodaysDeals);

  QPushButton* tool_buttons[] = {ui->btnSave, ui->btnClock};
  for (QPushButton* button : tool_buttons) {
    button->setStyleSheet(QString("QPushButton {"
                                  "  background-color: transparent;"
                                  "}"
                                  "QPushButton:hover {"
                                  "  background-color: #%1;"
                                  "}")
                              .arg(hover.rgb(), 0, 16));
  }
}

BondDetailAllMarket::~BondDetailAllMarket() { delete ui; }

void BondDetailAllMarket::paintEvent(QPaintEvent* event) {
  QRect r = rect();
  r.setBottom(m_bestTable->frameGeometry().top());
  QStylePainter painter(this);
  const QColor backgroud = StyleMgr::instance().color("BasicPlate");
  painter.fillRect(r, backgroud);

  if (ui->DetailContainer->isVisible()) {
    painter.fillRect(ui->DetailContainer->geometry(), backgroud);
  }
}

void BondDetailAllMarket::setDetailData(QSharedPointer<DetailData> data) {
  m_data = data;

  initBestPriceList();

  connect(m_data.get(), &DetailData::brokerBestQuoteChanged, m_bestBidOfr,
          &BestBidOfr::onBrokerBestQuoteChanged);
  // connect(m_data.get(), &DetailData::brokerBestPriceChanged, this,
  // &BondDetailAllMarket::onBestPriceChanged);
  connect(m_data.get(), &DetailData::bondChanged, this,
          &BondDetailAllMarket::onBondChanged);

  connect(m_data.get(), &DetailData::SHFIDataChanged, this,
          &BondDetailAllMarket::onSHFIDataArrived);

  onBondChanged();
}

void BondDetailAllMarket::setQuoteType(QuoteTypeId type,
                                       const std::vector<bool>& mask) {
  if (m_quote_type == type) return;

  ui->Title->setVisible(type <= CFETS);

  {
    ui->cmbSource->setVisible(type == AllMarket);
    ui->lblSource->setVisible(type == AllMarket);
    if (type == AllMarket) {
      if (0 == ui->cmbSource->count()) {
        ui->cmbSource->setEnabled(false);
        const int DetailQuoteTableTypes[] = {-1, DETAILOTHERTYPE_BROKER,
                                             DETAILOTHERTYPE_CFETS,
                                             DETAILOTHERTYPE_EXCHANGE};
        for (int i = AllMarket; i < QuoteTypeCount; ++i) {
          if (mask[i] && i /*To skip AllMarket but still go to else branch*/) {
            ui->cmbSource->addItem(kMarkNameList[i]);
            DetailQuoteTable* p = new DetailQuoteTable(
                ui->DetailTable, m_data, DetailQuoteTableTypes[i]);
            ui->DetailTable->addWidget(p);
            connect(ui->buttonGroup, &QButtonGroup::idToggled, p,
                    &DetailQuoteTable::onTabClicked);
          } else {
            ui->DetailTable->addWidget(
                new QWidget(ui->DetailTable));  // we still add a blank page, so
                                                // that the currentIndex can be
                                                // treated as QuoteTypeId
          }
        }

        ui->cmbSource->setCurrentIndex(0);
        on_cmbSource_currentTextChanged(ui->cmbSource->currentText());

        ui->cmbSource->setEnabled(true);

        if (mask[SHFixed]) {
          m_data->reqSHFIData(true);
        }
      }
    } else {
      ui->cmbSource->setCurrentText(kMarkNameList[type]);
    }
  }

  {
    ui->ClearSpeed->clear();
    const QStringList ClearSpeedLevels = {kAll, kT0, kT1};
    ui->ClearSpeed->addItems(ClearSpeedLevels);

    if (type < CFETS) {
      const QStringList ClearSpeedLevels2 = {kFWD, kSpot};
      ui->ClearSpeed->addItems(ClearSpeedLevels2);
    }
  }

  ui->BestBOBroker->setVisible(Broker == type);

  if (m_bestTableSet) {
    m_bestTableSet->setColumnHide(
        BestTableColumnID::Buyer,
        !(type == AllMarket || type == CFETS || type == SHFixed));
    m_bestTableSet->setColumnHide(
        BestTableColumnID::Seller,
        !(type == AllMarket || type == CFETS || type == SHFixed));
  }

  QStandardItemModel* model =
      dynamic_cast<QStandardItemModel*>(m_bestTable->table()->model());
  if (model) {
    for (int row = 0; row < model->rowCount(); ++row) {
      QStandardItem* item = model->item(row);
      if (item) {
        bool ok = true;
        const int broker_id = item->data(BrokerIdRole).toInt(&ok);
        const int broker_sub_index = item->data(DataIdRole).toInt(&ok);
        if (ok) {
          if (type != AllMarket) {
            if (MARKET_CFETS == broker_id)
              m_bestTable->table()->setRowHidden(row, (type != CFETS));
            else if (MARKET_EXCHANGE == broker_id)
              m_bestTable->table()->setRowHidden(row, (type != Exchange));
            else if (MARKET_SHFI == broker_id) {
              if (type == SHFixed) {
                m_bestTable->table()->setRowHidden(row, false);
                if (broker_sub_index <= 1) {
                  item->setData(1, DataIdRole);  // switch to 1 to show 1
                }
              } else {
                m_bestTable->table()->setRowHidden(row, true);
              }
            } else  // broker
              m_bestTable->table()->setRowHidden(row, (type != Broker));
          } else {
            if (MARKET_CFETS == broker_id)
              m_bestTable->table()->setRowHidden(row, !mask[CFETS]);
            else if (MARKET_EXCHANGE == broker_id)
              m_bestTable->table()->setRowHidden(row, !mask[Exchange]);
            else if (MARKET_SHFI == broker_id) {
              if (broker_sub_index <= 1) {
                m_bestTable->table()->setRowHidden(row, !mask[SHFixed]);
                item->setData(0, DataIdRole);  // switch to 0 to show [上证固收]
              } else
                m_bestTable->table()->setRowHidden(row, true);
            } else  // broker
              m_bestTable->table()->setRowHidden(row, !mask[Broker]);
          }
        }
      }
    }
  }

  m_quote_type = type;
}

QVector<QPair<int, int>> getBrokerList() {
  QVector<QPair<int, int>> ret;

  const CBrokerList& brokerList =
      SSUserAccountManager::instance().GetReadonlyBroker();
  std::vector<int> sortID = brokerList.GetSortKey();

  int nSortid = 0;
  CBrokerUnit stUnit;
  for (int i = 0; i < (int)sortID.size(); i++) {
    nSortid = sortID[i];
    for (CBrokerList::BrokerMap::const_iterator itor =
             brokerList.GetBrokerMap().begin();
         itor != brokerList.GetBrokerMap().end(); ++itor) {
      stUnit = itor->second;
      if (!CBrokerList::IsValidBroker(stUnit.m_brokerID)) continue;
      if (stUnit.m_brokerID != nSortid ||
          (!stUnit.m_enableFlag_BOND && !stUnit.m_enableFlag_NCD))
        continue;

      ret.push_back(
          {itor->second.m_brokerID,
           0});  // QString::fromLocal8Bit(itor->second.m_brokerName.c_str())
      break;
    }
  }
  return ret;
}

/*void BondDetailAllMarket::onBestPriceChanged(std::map<std::string, int>
changes)
{
    updateList();
    for (auto bpChanage : changes)
    {
        FlashInfo fi;
        fi.id = QString::fromStdString(bpChanage.first);
        fi.entireRow = false;

        if ((bpChanage.second & 1) == 1)
        {
            fi.cols.push_back(1);
            fi.cols.push_back(2);
        }

        if ((bpChanage.second & 2) == 2)
        {
            fi.cols.push_back(3);
            fi.cols.push_back(4);
        }
        m_bestTable->addFlashInfo(fi);
    }
}*/

void BondDetailAllMarket::initBestPriceList() {
  m_bestTableSet = new STableColumnSet(m_bestTable, "BrokerBestPrice", this);
  m_bestTableSet->setTableWidthFixed(false);

  BEGIN_COLUMN;
  ADD_COLUMN(BestTableColumnID::Type, m_bestTableSet, "类型", 0, 50, 12, -1,
             false, (Qt::Alignment)(Qt::AlignVCenter | Qt::AlignLeft), kFixed,
             "");
  ADD_COLUMN(BestTableColumnID::Buyer, m_bestTableSet, "买方", 0, 60, 12, -1,
             false, (Qt::Alignment)(Qt::AlignVCenter | Qt::AlignLeft), kFixed,
             "");
  ADD_COLUMN(BestTableColumnID::VolBid, m_bestTableSet, "Vol.Bid", 0, -1, 12,
             0.25, false, (Qt::Alignment)(Qt::AlignVCenter | Qt::AlignRight),
             kAuto, "");
  ADD_COLUMN(BestTableColumnID::Bid, m_bestTableSet, "Bid", 0, -1, 12, 0.25,
             false, (Qt::Alignment)(Qt::AlignVCenter | Qt::AlignRight), kAuto,
             "");
  ADD_COLUMN(BestTableColumnID::Ofr, m_bestTableSet, "Ofr", 0, -1, 12, 0.25,
             false, (Qt::Alignment)(Qt::AlignVCenter | Qt::AlignRight), kAuto,
             "");
  ADD_COLUMN(BestTableColumnID::VolOfr, m_bestTableSet, "Vol.Ofr", 0, -1, 12,
             0.25, false, (Qt::Alignment)(Qt::AlignVCenter | Qt::AlignRight),
             kAuto, "");
  ADD_COLUMN(BestTableColumnID::Seller, m_bestTableSet, "卖方", 0, 60, 12, -1,
             false, (Qt::Alignment)(Qt::AlignVCenter | Qt::AlignLeft), kFixed,
             "");
  ADD_COLUMN(BestTableColumnID::UpdateTime, m_bestTableSet, tr("更新时间"), 0,
             60, 12, -1, false,
             (Qt::Alignment)(Qt::AlignVCenter | Qt::AlignRight), kFixed, "");

  BrokerCorpDelegate* brokerCorpDelegate = new BrokerCorpDelegate(m_bestTable);
  m_bestTable->table()->setItemDelegateForColumn(0, brokerCorpDelegate);

  m_bestTable->table()->horizontalHeader()->show();

  {
    QFont f = font();
    f.setPixelSize(13);
    f.setBold(true);

    QFont timeF = f;
    timeF.setPixelSize(12);

    const int max_col_count = BestTableColumnID::MAX_COL_COUNT;
    QVector<QPair<int, int>> brokerList = getBrokerList();

    brokerList.push_back({MARKET_CFETS, CCFETSQuote::XBOND});
    brokerList.push_back({MARKET_CFETS, CCFETSQuote::MARKETMAKER});
    brokerList.push_back({MARKET_SHFI, 0});
    // brokerList.push_back({MARKET_SHFI, 1});
    brokerList.push_back({MARKET_SHFI, 2});
    brokerList.push_back({MARKET_SHFI, 3});
    brokerList.push_back({MARKET_SHFI, 4});
    brokerList.push_back({MARKET_SHFI, 5});
    brokerList.push_back({MARKET_EXCHANGE, 0});

    const int max_row_count = brokerList.count();

    m_bestTable->setFixedHeight(
        kRowHeight *
        qMax(1 + 5, max_row_count + 1 - 4)); /*1:column header; 4: hide SHFI*/

    DefaultTableModel* model = new DefaultTableModel(this);
    model->setRowCount(max_row_count);
    model->setTable(m_bestTable);
    m_bestTable->table()->setModel(model);

    for (int row = 0; row < max_row_count; ++row) {
      for (int col = 0; col < max_col_count; ++col) {
        QStandardItem* item = new QStandardItem();
        model->setItem(row, col, item);
        item->setData((int)(Qt::AlignRight | Qt::AlignVCenter),
                      Qt::TextAlignmentRole);
        item->setData(StyleMgr::instance().color("Highlight"),
                      Qt::ForegroundRole);
        item->setData(StyleMgr::instance().color("BasicPlate"),
                      Qt::BackgroundRole);
        // item->setData(report.m_company_id, DataIdRole);
        item->setFont((col != BestTableColumnID::UpdateTime) ? f : timeF);
      }
    }

    for (int row = 0; row < max_row_count; ++row) {
      QStandardItem* item = nullptr;
      if ((item = model->item(row, BestTableColumnID::Type))) {
        item->setData(brokerList[row].first, BrokerIdRole);
        item->setData(brokerList[row].second, DataIdRole);
      }
      if ((item = model->item(row, BestTableColumnID::Bid))) {
        item->setData(StyleMgr::instance().color("Bid_GVN_H1"),
                      Qt::ForegroundRole);
      }
      if ((item = model->item(row, BestTableColumnID::Ofr))) {
        item->setData(StyleMgr::instance().color("Ofr_TKN_H1"),
                      Qt::ForegroundRole);
      }
      if ((item = model->item(row, BestTableColumnID::Buyer))) {
        item->setData((int)(Qt::AlignLeft | Qt::AlignVCenter),
                      Qt::TextAlignmentRole);
      }
      if ((item = model->item(row, BestTableColumnID::Seller))) {
        item->setData((int)(Qt::AlignLeft | Qt::AlignVCenter),
                      Qt::TextAlignmentRole);
      }

      m_bestTable->table()->setRowHeight(row, kRowHeight);
    }
  }

  m_bestTableSet->apply();
}

static std::unique_ptr<REPORT> getDealExListRptMap(bool disAll, int brokerId,
                                                   const CBondInfo& bond,
                                                   int clearSpeed) {
  char cBroker[8] = {0};

#ifdef _MSC_VER
  sprintf_s(cBroker, sizeof(cBroker), "%d", brokerId);
#else
  snprintf(cBroker, sizeof(cBroker), "%d", brokerId);
#endif
  std::unique_ptr<REPORT> rpt;
  rpt.reset(new REPORT);
  bool getRpt = false;
  if (clearSpeed <= 0)
    getRpt = CBondContainer::instance().GetCompanyRepByKey(
        bond.GetCombBondKey(), cBroker, *rpt.get());
  else {
    getRpt = CBondContainer::instance().GetCompanyRepByKeyAndSettlement(
        bond.GetCombBondKey(), cBroker, clearSpeed, *rpt.get());
  }

  if (getRpt) {
    ;
  } else if (disAll) {
    memset(rpt.get(), 0, sizeof(REPORT));
    FMTBUF(rpt->m_company_id, "%d", brokerId);
  }

  return rpt;
}

void BondDetailAllMarket::updateList() {
  // const bool isRating = m_data->bond().IsRatingDebt();
  // const bool isExchange = m_data->bond().IsExchange();
  // const bool isDatafeed =
  // (strcmp(SSUserAccountManager::instance().GetPermission().GetValue(USER_PERMISSION_QB_PRO),
  // "2") == 0); const bool isQMValid =
  // (strcmp(SSUserAccountManager::instance().GetPermission().GetValue(USER_PERMISSION_NEW_QM),
  // "1") == 0
  //                  &&
  //                  strcmp(SSUserAccountManager::instance().GetPermission().GetValue(USER_PERMISSION_QM_BROKER_CONTACT),
  //                  "1") == 0);
  // const bool isQMMoveFront = (!isDatafeed && isQMValid);

  // QFont f = font();
  // f.setPixelSize(13);
  // f.setBold(true);

  // QFont timeF = f;
  // timeF.setPixelSize(12);

  QStandardItemModel* model =
      dynamic_cast<QStandardItemModel*>(m_bestTable->table()->model());
  if (model) {
    for (int row = 0; row < model->rowCount(); ++row) {
      QStandardItem* item0 = model->item(row);
      if (item0) {
        bool ok = true;
        const int broker_id = item0->data(BrokerIdRole).toInt(&ok);
        if (ok) {
          if (MARKET_CFETS == broker_id) {
            const CCFETSQuote::CFETSQUOTETYPE cfets_quote_type =
                static_cast<CCFETSQuote::CFETSQUOTETYPE>(
                    item0->data(DataIdRole).toInt(&ok));
            CBondContainer& bc = CBondContainer::instance();
            const CBondInfo& bi = m_data->bond();
            CFETSQUOTE quote;
            if (bc.GetCFETSQuoteByKey(bi.GetBondKey(), bi.GetListedMarket(),
                                      cfets_quote_type, quote, m_clearSpeed)) {
              QStandardItem* item = nullptr;
              if ((item = model->item(row, BestTableColumnID::Buyer))) {
                BondUtility::DisplayCFETSCompany(cfets_quote_type,
                                                 quote.m_BidCompanyName, item);
              }
              if ((item = model->item(row, BestTableColumnID::Seller))) {
                BondUtility::DisplayCFETSCompany(cfets_quote_type,
                                                 quote.m_OfrCompanyName, item);
              }
              if ((item = model->item(row, BestTableColumnID::VolBid))) {
                BondUtility::DisplayCFETSVolumn(quote, true, item);
              }
              if ((item = model->item(row, BestTableColumnID::Bid))) {
                const auto& txt =
                    SSTools::PriceRemoveZero(quote.m_BidPriceYield, 2);
                item->setData(QString::fromLocal8Bit(txt.c_str()),
                              Qt::DisplayRole);
              }
              if ((item = model->item(row, BestTableColumnID::Ofr))) {
                const auto& txt =
                    SSTools::PriceRemoveZero(quote.m_OfrPriceYield, 2);
                item->setData(QString::fromLocal8Bit(txt.c_str()),
                              Qt::DisplayRole);
              }
              if ((item = model->item(row, BestTableColumnID::VolOfr))) {
                BondUtility::DisplayCFETSVolumn(quote, false, item);
              }
              if ((item = model->item(row, BestTableColumnID::UpdateTime))) {
                BondUtility::SetUpdateTimeCol(item, quote.m_time);
                // item->setData(timeF, Qt::FontRole);
              }
            }
          } else if (MARKET_EXCHANGE == broker_id) {
            CBondContainer& bc = CBondContainer::instance();
            const CBondInfo& bi = m_data->bond();
            XCQUOTE report;
            if (bc.GetXCQuoteByKey(bi.GetBondKey(), bi.GetListedMarket(),
                                   report)) {
              QStandardItem* item = nullptr;
              if ((item = model->item(row, BestTableColumnID::VolBid))) {
                QString strTemp = "--";
                if (strcmp(report.m_BidVol, "") != 0 &&
                    report.m_BidVol[0] != '\0' && atof(report.m_BidVol) > 0.01)
                  strTemp = QString::fromLocal8Bit(report.m_BidVol);
                item->setData(strTemp, Qt::DisplayRole);
              }
              if ((item = model->item(row, BestTableColumnID::Bid))) {
                QString strTemp;
                char cPrice[12] = {0};
                FIELDCOPY(
                    cPrice,
                    report.m_BidPriceClean);  // 5.3.4全部改为净价/全价展示
                if (strcmp(cPrice, "Bid") == 0)
                  strTemp = "Bid";
                else if (strcmp(cPrice, "") != 0)
                  BondUtility::translateDonePrice(cPrice, strTemp);
                item->setData(strTemp, Qt::DisplayRole);
              }
              if ((item = model->item(row, BestTableColumnID::Ofr))) {
                QString strTemp;
                char cPrice[12] = {0};
                FIELDCOPY(
                    cPrice,
                    report.m_OfrPriceClean);  // 5.3.4全部改为净价/全价展示
                if (strcmp(cPrice, "Ofr") == 0)
                  strTemp = "Ofr";
                else if (strcmp(cPrice, "") != 0)
                  BondUtility::translateDonePrice(cPrice, strTemp);
                item->setData(strTemp, Qt::DisplayRole);
              }
              if ((item = model->item(row, BestTableColumnID::VolOfr))) {
                QString strTemp = "--";
                if (strcmp(report.m_OfrVol, "") != 0 &&
                    report.m_OfrVol[0] != '\0' && atof(report.m_OfrVol) > 0.01)
                  strTemp = QString::fromLocal8Bit(report.m_OfrVol);
                item->setData(strTemp, Qt::DisplayRole);
              }
              if ((item = model->item(row, BestTableColumnID::UpdateTime))) {
                const time_t& t_Current = report.m_time;
                BondUtility::SetUpdateTimeCol(item, t_Current);
              }
            }
          } else if (MARKET_SHFI == broker_id)
            ;
          else {  // broker
            std::unique_ptr<REPORT> report = getDealExListRptMap(
                true, broker_id, m_data->bond(), m_clearSpeed);
            const bool isBidValid =
                (strcmp(report->m_bidinfo.m_price_status, "0") != 0);
            const bool isOfrValid =
                (strcmp(report->m_askinfo.m_price_status, "0") != 0);
            QStandardItem* item = nullptr;
            item = model->item(row, BestTableColumnID::VolBid);
            if (item) {
              BondUtility::DisplayVolumn(report->m_bidinfo, isBidValid, false,
                                         item);
            }
            item = model->item(row, BestTableColumnID::Bid);
            if (item) {
              BondUtility::DisplayPriceNew(
                  report->m_bidinfo, isBidValid,
                  StyleMgr::instance().color("Bid_GVN_H1"), false, false, false,
                  false, m_clearSpeed > 0, item);
            }
            item = model->item(row, BestTableColumnID::Ofr);
            if (item) {
              BondUtility::DisplayPriceNew(
                  report->m_askinfo, isOfrValid,
                  StyleMgr::instance().color("Ofr_TKN_H1"), false, false, false,
                  false, m_clearSpeed > 0, item);
            }
            item = model->item(row, BestTableColumnID::VolOfr);
            if (item) {
              BondUtility::DisplayVolumn(report->m_askinfo, isOfrValid, false,
                                         item);
            }
            item = model->item(row, BestTableColumnID::UpdateTime);
            if (item) {
              time_t t_Current = 0;
              t_Current = qMax(report->m_time, report->m_create_time);
              BondUtility::SetUpdateTimeCol(item, t_Current);
              // item->setData(timeF, Qt::FontRole);
            }
          }
        }
      }
    }
  }
}

void BondDetailAllMarket::updateDisplayMktStream(QuoteTypeId type) {
  // TODO:考虑线程问题,更改当前的bond
  auto& mktStream = m_mktStream[type];
  mktStream.clear();
  // TODO: m_lstMktStreamDeal
  const auto& mktMap =
      (Broker == type) ? m_data->marketStream() : m_data->cfetsMarketStream();
  std::list<xQBMarketStreamUnit_c> mkts;
  for (auto& m : mktMap) mkts.push_back(m.second);

  const auto& mkdDeal =
      (Broker == type) ? m_data->marketDeal() : m_data->marketDealCfets();
  for (auto& m : mkdDeal) mkts.push_back(m.second);
  mkts.sort();

  mktStream.insert(mktStream.end(), mkts.begin(), mkts.end());

  // m_detailQuoteTable->setRealDataCount(mktStream.size());
}

void BondDetailAllMarket::on_ClearSpeed_currentTextChanged(
    const QString& arg1) {
  if (arg1 == kAll) {
    m_clearSpeed = 0;
  } else if (arg1 == kT0) {
    m_clearSpeed = 1;
  } else if (arg1 == kT1) {
    m_clearSpeed = 2;
  } else if (arg1 == kFWD) {
    m_clearSpeed = 4;
  } else if (arg1 == kSpot) {
    m_clearSpeed = 3;
  }

  if (m_data) {
    m_data->setClearSpeed(m_clearSpeed);
    updateList();
  }
}

void BondDetailAllMarket::on_cmbSource_currentTextChanged(const QString& arg1) {
  m_source_type = static_cast<QuoteTypeId>(kMarkNameList.indexOf(arg1));
  ui->DetailTable->setCurrentIndex(m_source_type);
}

void BondDetailAllMarket::onBondChanged() {
  if (m_data) {
    m_data->reqMarketStream(0);
    m_data->reqCfetsMarketStream(0);

    updateList();
  }
}

void BondDetailAllMarket::onSHFIDataArrived(
    const QList<xQBSHFIQuoteUnit_c>& datas) {
  qDebug() << "onSHFIDataArrived";
  // TODO: update [datas] into table: m_bestTable
  QStandardItemModel* model =
      dynamic_cast<QStandardItemModel*>(m_bestTable->table()->model());
  if (!model) return;

  auto getSHFIRows = [model]() {
    QVector<int> SHFIRows;
    for (int row = 0; row < model->rowCount(); ++row) {
      QStandardItem* item0 = model->item(row);
      if (!item0) continue;

      bool ok = true;
      const int broker_id = item0->data(BrokerIdRole).toInt(&ok);
      if (!ok) continue;

      if (MARKET_SHFI != broker_id) continue;
      SHFIRows.push_back(row);
    }
    return SHFIRows;
  };

  const QVector<int>& SHFIRows = getSHFIRows();

  if (SHFIRows.isEmpty()) return;

  auto clearSHFIRows = [model](const QVector<int>& SHFIRows) {
    for (const auto& row : SHFIRows) {
      QStandardItem* item = nullptr;
      for (int col = BestTableColumnID::Buyer;
           col < BestTableColumnID::MAX_COL_COUNT; ++col) {
        if ((item = model->item(row, col))) {
          item->setData("--", Qt::DisplayRole);
        }
      }

      if ((item = model->item(row, BestTableColumnID::UpdateTime))) {
        item->setData(QDateTime(), DataIdRole);
      }
    }
  };

  auto updateSHFIRow = [model](const int& row, const xQBSHFIQuoteUnit_c& data) {
    QString szBidInst, szVolBid, szBid, szOfr, szVolOfr, szOfrInst, szBidYield,
        szOfrYield, szMark;
    szBidInst = szVolBid = szBid = szOfr = szVolOfr = szOfrInst = "--";

    {
      const QBSHFIQuote5& bid = data.m_Bid;
      szBidInst = QString::fromLocal8Bit(bid.m_Institution);
      const char* bidPrice = bid.m_Price;
      const char* volBid = bid.m_Vol;
      const char* bidYield = bid.m_Yield;

      if (fabs(atof(bidPrice)) > 0.0001) {
        szBid = SSTools::FormatePrice(bidPrice);
        szBid = SSTools::PriceRemoveZero(szBid, 2);
      } else {
        szBid = "--";
      }

      if (strcmp(volBid, "") != 0 && volBid[0] != '\0' && atof(volBid) > 0.01) {
        szVolBid = QString::number(atof(volBid) / 10, 'f', 2);
        szVolBid = SSTools::PriceRemoveZero(szVolBid, 0);
      }

      if (strcmp(bidYield, "") != 0) szBidYield = bidYield;

      const QBSHFIQuote5& ofr = data.m_Ofr;
      szOfrInst = QString::fromLocal8Bit(ofr.m_Institution);
      const char* ofrPrice = ofr.m_Price;
      const char* volOfr = ofr.m_Vol;
      const char* ofrYield = ofr.m_Yield;

      if (fabs(atof(ofrPrice)) > 0.0001) {
        szOfr = SSTools::FormatePrice(ofrPrice);
        szOfr = SSTools::PriceRemoveZero(szOfr, 2);
      } else {
        szOfr = "--";
      }

      if (strcmp(volOfr, "") != 0 && volOfr[0] != '\0' && atof(volOfr) > 0.01) {
        // szVolOfr.Format(_T("%s"), SSA2W(volOfr));
        // szVolOfr.Format(_T("%.2f"), atof(volOfr) / 10);
        szVolOfr = QString::number(atof(volOfr) / 10, 'f', 2);
        szVolOfr = SSTools::PriceRemoveZero(szVolOfr, 0);
      }
      if (strcmp(ofrYield, "") != 0) szOfrYield = ofrYield;

      // szMark.Format(_T("%s_%s_%s_%s"), szBidYield, szBid, szOfrYield, szOfr);
      szMark = QString("%s_%s_%s_%s").arg(szBidYield, szBid, szOfrYield, szOfr);
    }

    {
      QStandardItem* item = nullptr;
      if ((item = model->item(row, BestTableColumnID::Buyer))) {
        item->setData(szBidInst, Qt::DisplayRole);
      }
      if ((item = model->item(row, BestTableColumnID::Seller))) {
        item->setData(szOfrInst, Qt::DisplayRole);
      }
      if ((item = model->item(row, BestTableColumnID::VolBid))) {
        item->setData(szVolBid, Qt::DisplayRole);
      }
      if ((item = model->item(row, BestTableColumnID::Bid))) {
        item->setData(szBid, Qt::DisplayRole);
      }
      if ((item = model->item(row, BestTableColumnID::Ofr))) {
        item->setData(szOfr, Qt::DisplayRole);
      }
      if ((item = model->item(row, BestTableColumnID::VolOfr))) {
        item->setData(szVolOfr, Qt::DisplayRole);
      }
      if ((item = model->item(row, BestTableColumnID::UpdateTime))) {
        BondUtility::SetUpdateTimeCol(item, data.m_Time);
      }
    }
  };

  for (const auto& data : datas) {
    const QDateTime updateTime =
        QDateTime::fromSecsSinceEpoch(data.m_Time / 1000);

    // QStandardItem* item = nullptr;
    if (QStandardItem* item =
            model->item(SHFIRows[0], BestTableColumnID::UpdateTime)) {
      const QDateTime lastUpdateTime = item->data(DataIdRole).toDateTime();
      if (updateTime != lastUpdateTime) {
        clearSHFIRows(SHFIRows);
      }
    }

    auto iter =
        std::find_if(SHFIRows.begin(), SHFIRows.end(), [model](const int row) {
          if (QStandardItem* item =
                  model->item(row, BestTableColumnID::UpdateTime)) {
            const QDateTime lastUpdateTime =
                item->data(DataIdRole).toDateTime();
            return lastUpdateTime.isNull();
          }
          return false;
        });
    if (iter == SHFIRows.end()) return;
    const int updateRow = *iter;
    updateSHFIRow(updateRow, data);
    if (QStandardItem* item =
            model->item(updateRow, BestTableColumnID::UpdateTime)) {
      item->setData(updateTime, DataIdRole);
    }
  }
}
